package com.ry.quartz.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class QuartzJobService {

	@Autowired
	private Scheduler scheduler;

	public void addJob(String clazzName, String jobName, String jobGroupName, String cronExpression) {
		try {
			Class cls = Class.forName(clazzName);

			// 构建job信息
			JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, jobGroupName).build();

			// 表达式调度构建器(即任务执行的时间)
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);

			// 按新的cronExpression表达式构建一个新的trigger
			CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
					.withSchedule(scheduleBuilder).build();

			scheduler.scheduleJob(jobDetail, trigger);
			// 启动
			if (!scheduler.isShutdown()) {
				scheduler.start();
			}
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public boolean modifyJob(String name, String group, String cron) {
		Date date = null;
		try {
			TriggerKey triggerKey = new TriggerKey(name, group);
			CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			String oldTime = cronTrigger.getCronExpression();
			if (!oldTime.equalsIgnoreCase(cron)) {
				CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
				CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(name, group)
						.withSchedule(cronScheduleBuilder).build();
				date = scheduler.rescheduleJob(triggerKey, trigger);
			}
			System.out.println(date.toString());
			return date != null;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return date != null;
	}

	public void pauseJob(String name, String group) {
		try {
			scheduler.pauseJob(JobKey.jobKey(name, group));
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void resumeJob(String name, String group) {
		try {
			scheduler.resumeJob(JobKey.jobKey(name, group));
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void deleteJob(String jobName, String jobGroupName){
		try {
			scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));
			scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));
			scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public List<Map<String, Object>> getAllJob() {
		List<Map<String, Object>> jobList = null;
		try {
			GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
			Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
			jobList = new ArrayList<>();
			for (JobKey jobKey : jobKeys) {
				List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
				for (Trigger trigger : triggers) {
					Map<String, Object> job = new HashMap<>();
					job.put("jobName", jobKey.getName());
					job.put("jobGroupName", jobKey.getGroup());
					job.put("trigger", trigger.getKey());
					Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
					job.put("jobStatus", triggerState.name());
					if (trigger instanceof CronTrigger) {
						CronTrigger cronTrigger = (CronTrigger) trigger;
						String cronExpression = cronTrigger.getCronExpression();
						job.put("cronExpression", cronExpression);
					}
					jobList.add(job);
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return jobList;
	}

}
